package org.stvd.service.workflow.leave.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.stvd.common.Consts;
import org.stvd.common.DepAndUserHolder;
import org.stvd.common.SecurityUserHolder;
import org.stvd.common.utils.ServiceResult;
import org.stvd.common.workflow.WorkflowConsts;
import org.stvd.common.workflow.enums.WorkflowApplyStatusEnum;
import org.stvd.core.dto.QueryResult;
import org.stvd.core.util.DateUtil;
import org.stvd.core.util.IdWorker;
import org.stvd.core.util.StringUtil;
import org.stvd.entities.admin.Users;
import org.stvd.entities.message.BsMessageInfo;
import org.stvd.entities.workflow.WfIndex;
import org.stvd.entities.workflow.leave.BsLeaveInfo;
import org.stvd.repository.workflow.WfIndexDao;
import org.stvd.repository.workflow.WfLogsDao;
import org.stvd.repository.workflow.leave.BsLeaveInfoDao;
import org.stvd.service.admin.UsersService;
import org.stvd.service.base.impl.BaseServiceImpl;
import org.stvd.service.workflow.leave.BsLeaveInfoService;
 
/**
 * @Title BsLeaveInfoServiceImpl
 * @Destribution:请假信息业务层实现类
 * @author fenglong
 * @date 2020年11月2日
 */
@Service("BsLeaveInfoService")
public class BsLeaveInfoServiceImpl extends BaseServiceImpl<BsLeaveInfo> implements BsLeaveInfoService {
 
    @Autowired
    private UsersService usersService;
    @Resource(name = "BsLeaveInfoDao")
    private BsLeaveInfoDao bsLeaveInfoDao;
    @Autowired
    WfIndexDao wfIndexDao;
    @Autowired
    WfLogsDao wfLogsDao;
 
    @Override
    public QueryResult<Map<String, Object>> getQueryResult(int i, Integer pageSize, String depName, String empName,
            Date startDate, Date endDate, String userId) {
        return bsLeaveInfoDao.getQueryResult(i, pageSize, depName, empName, startDate, endDate, userId,"");
    }
 
    @Override
    public ServiceResult<Map<String, Object>> insertLeaveInfo(BsLeaveInfo bsLeaveInfo, WfIndex wfIndex,
            Map<String, Object> variables) {
        ServiceResult<Map<String, Object>> serviceResult = new ServiceResult<Map<String, Object>>();
        if (bsLeaveInfo == null) {
            serviceResult.setParamError();
            return serviceResult;
        }
        if (bsLeaveInfo.getStartDate() == null || bsLeaveInfo.getEndDate() == null) {
            bsLeaveInfo.setStartDate(bsLeaveInfo.getStartDateT());
            bsLeaveInfo.setEndDate(bsLeaveInfo.getEndDateT());
        }
        if (bsLeaveInfo.getEndDate().before(bsLeaveInfo.getStartDate())) {
            serviceResult.setParamError("结束时间应晚于开始时间！");
            return serviceResult;
        }
        bsLeaveInfo.setId(IdWorker.getInstance().nextId());
        bsLeaveInfo.setAuditStatus(WorkflowApplyStatusEnum.Waiting.getValue());
        bsLeaveInfo.setCreateUser(SecurityUserHolder.getCurrentUserid());
        bsLeaveInfo.setCreateTime(DateUtil.getSystemDate());
        bsLeaveInfo.setProcessId(wfIndex.getProcInstId());
        WfIndex wfIndexNew = wfIndexDao.findByProcInstId(wfIndex.getProcInstId());
        if (wfIndexNew != null) {
            String uses = DepAndUserHolder.getApproveUserTaskInfoString(SecurityUserHolder.getCurrentUserid(),
                    wfIndexNew.getProcDefId());
            String usesName = DepAndUserHolder.getApproveUserTaskNameString(uses);
            bsLeaveInfo.setAuditUid(uses);
            bsLeaveInfo.setAuditUname(usesName);
        }
        bsLeaveInfoDao.insert(bsLeaveInfo);
        serviceResult.setMessage("申请提交成功！");
        return serviceResult;
    }
 
    @Override
    @Transactional
    public ServiceResult<Map<String, Object>> deleteLeaveInfo(String processInstanceId) {
        ServiceResult<Map<String, Object>> serviceResult = new ServiceResult<Map<String, Object>>();
        if (StringUtil.isEmpty(processInstanceId)) {
            serviceResult.setParamError();
            return serviceResult;
        }
        BsLeaveInfo bsLeaveInfo = findByProcessId(processInstanceId);
        if (bsLeaveInfo == null) {
            serviceResult.setParamError();
            return serviceResult;
        }
        bsLeaveInfoDao.delete(BsLeaveInfo.class, bsLeaveInfo.getId());
        serviceResult.setMessage("删除成功！");
        return serviceResult;
    }
 
    @Override
    public BsLeaveInfo findByProcessId(String processInstanceId) {
        return bsLeaveInfoDao.findByProcessId(processInstanceId);
    }
 
    @Override
    public QueryResult<Map<String, Object>> queryLeaveApproResult(int i, Integer pageSize, String auditStatus,
            String uid) {
        // TODO Auto-generated method stub
        String role = DepAndUserHolder.getUserRoleInfo(uid, Consts.GUID).get(0).getRoleCode();
        return bsLeaveInfoDao.queryLeaveResult(i, pageSize, auditStatus, uid, role);
 
    }
 
    @Override
    public ServiceResult<Map<String, Object>> claimLeave(String processInstanceId) {
        ServiceResult<Map<String, Object>> serviceResult = new ServiceResult<Map<String, Object>>();
        if (StringUtil.isEmpty(processInstanceId)) {
            serviceResult.setParamError();
            return serviceResult;
        }
        BsLeaveInfo bsLeaveInfo = findByProcessId(processInstanceId);
        if (bsLeaveInfo == null) {
            serviceResult.setParamError();
            return serviceResult;
        }
        if (WorkflowApplyStatusEnum.Waiting.getValue().equals(bsLeaveInfo.getAuditStatus())) {
            bsLeaveInfo.setAuditStatus(WorkflowApplyStatusEnum.InReview.getValue());
            bsLeaveInfo.setModifyTime(DateUtil.getSystemDate());
            bsLeaveInfoDao.update(bsLeaveInfo);
        }
        serviceResult.setMessage("签收成功！");
        return serviceResult;
    }
 
    @Override
    public ServiceResult<Map<String, Object>> approveLeave(String processInstanceId, Map<String, Object> variables) {
        ServiceResult<Map<String, Object>> serviceResult = new ServiceResult<Map<String, Object>>();
        if (StringUtil.isEmpty(processInstanceId) || variables == null) {
            serviceResult.setParamError();
            return serviceResult;
        }
        BsLeaveInfo bsLeaveInfo = findByProcessId(processInstanceId);
        if (bsLeaveInfo == null) {
            serviceResult.setParamError();
            return serviceResult;
        }
//        Calendar calendar = new GregorianCalendar();
        WfIndex index = wfIndexDao.findByProcInstId(processInstanceId);
        String auditName = "";
        String assignee = index.getAssignee();
        if (!StringUtil.isEmpty(assignee)) {
            auditName = usersService.findByPk(Users.class, assignee).getUname();
        }
        BsMessageInfo messageInfo = new BsMessageInfo();
        messageInfo.setId(IdWorker.getInstance().nextId());
        messageInfo.setCreateTime(DateUtil.getSystemDate());
        messageInfo.setCreateUser(SecurityUserHolder.getCurrentUserid());
        messageInfo.setTitle("项目审批");
        String nextKey = variables.get(WorkflowConsts.NEXT_TASK_KEY).toString();
        if ("manage_approve".equals(nextKey)) {
            bsLeaveInfo.setAuditStatus(WorkflowApplyStatusEnum.InReview.getValue());
            bsLeaveInfo.setModifyTime(DateUtil.getSystemDate());
            messageInfo.setContent(
                    bsLeaveInfo.getStartDate() + "-" + bsLeaveInfo.getEndDate() + "的请假申请" + "审批通过， 审批人：" + auditName);
        } else if ("process_end".equals(variables.get(WorkflowConsts.NEXT_TASK_KEY))) {
//            if (bsLeaveInfo.getLeaveDays().compareTo(new BigDecimal(1)) == -1) {    
//                BsAttendanceInfo bsAttendanceInfo = new BsAttendanceInfo();
//                bsAttendanceInfo.setId(IdWorker.getInstance().nextId());
//                bsAttendanceInfo.setDepId(bsLeaveInfo.getDepId());
//                bsAttendanceInfo.setDepName(bsLeaveInfo.getDepName());
//                bsAttendanceInfo.setEmpId(bsLeaveInfo.getEmpId());
//                bsAttendanceInfo.setEmpName(bsLeaveInfo.getEmpName());
//                bsAttendanceInfo.setAttendDate(
//                        DateUtil.getShortDate(DateUtil.toString(bsLeaveInfo.getStartDate(), "yyyy-MM-dd")));
//                bsAttendanceInfo.setStatus("2");
//                bsAttendanceInfo.setCreateUser(bsLeaveInfo.getCreateUser());
//                bsAttendanceInfo.setCreateTime(DateUtil.getSystemDate());
//                bsAttendanceInfoService.insert(bsAttendanceInfo);
//            } else {
//                int leaveDays = DateUtil.diffDate(
//                        DateUtil.getShortDate(DateUtil.toString(bsLeaveInfo.getEndDate(), "yyyy-MM-dd")),
//                        DateUtil.getShortDate(DateUtil.toString(bsLeaveInfo.getStartDate(), "yyyy-MM-dd")));
//                for (int i = 0; i < leaveDays; i++) {
//                    BsAttendanceInfo bsAttendanceInfo = new BsAttendanceInfo();
//                    bsAttendanceInfo.setId(IdWorker.getInstance().nextId());
//                    bsAttendanceInfo.setDepId(bsLeaveInfo.getDepId());
//                    bsAttendanceInfo.setDepName(bsLeaveInfo.getDepName());
//                    bsAttendanceInfo.setEmpId(bsLeaveInfo.getEmpId());
//                    bsAttendanceInfo.setEmpName(bsLeaveInfo.getEmpName());
//                    if (i == 0) {
//                        bsAttendanceInfo.setAttendDate(
//                                DateUtil.getShortDate(DateUtil.toString(bsLeaveInfo.getStartDate(), "yyyy-MM-dd")));
//                    } else {
//                        calendar.setTime(
//                                DateUtil.getShortDate(DateUtil.toString(bsLeaveInfo.getStartDate(), "yyyy-MM-dd")));
//                        calendar.add(calendar.DATE, i);
//                        bsAttendanceInfo.setAttendDate(calendar.getTime());
//                    }
//                    bsAttendanceInfo.setStatus("2");
//                    bsAttendanceInfo.setCreateUser(bsLeaveInfo.getCreateUser());
//                    bsAttendanceInfo.setCreateTime(DateUtil.getSystemDate());
//                    bsAttendanceInfoService.insert(bsAttendanceInfo);
//                }
//            }
            bsLeaveInfo.setAuditStatus(WorkflowApplyStatusEnum.Pass.getValue());
            bsLeaveInfo.setModifyTime(DateUtil.getSystemDate());
 
        }
        bsLeaveInfoDao.update(bsLeaveInfo);
        serviceResult.setMessage("审批完成！");
        return serviceResult;
    }
    /**
     * 驳回
     */
    @Override
    public ServiceResult<Map<String, Object>> refuseLeave(String processInstanceId, String jumpTaskKey,
            Map<String, Object> variables) {
        ServiceResult<Map<String, Object>> serviceResult = new ServiceResult<Map<String, Object>>();
        if (StringUtil.isEmpty(processInstanceId)) {
            serviceResult.setParamError();
            return serviceResult;
        }
        BsLeaveInfo bsLeaveInfo = findByProcessId(processInstanceId);
        WfIndex wfIndex = wfIndexDao.findByProcInstId(processInstanceId);
        String assignee = "";
        if (wfIndex != null) {
            if (!StringUtil.isEmpty(jumpTaskKey)) {
                assignee = DepAndUserHolder.getTargetTaskUids(bsLeaveInfo.getAuditUid(), jumpTaskKey);
                wfIndex.setAssignee(assignee);
            }
            wfIndex.setStatus(WorkflowApplyStatusEnum.Refuse.getValue());
            wfIndexDao.update(wfIndex);
        }
        bsLeaveInfo.setAuditStatus(WorkflowApplyStatusEnum.Refuse.getValue());
        bsLeaveInfo.setModifyTime(DateUtil.getSystemDate());
        bsLeaveInfoDao.update(bsLeaveInfo);
        return serviceResult;
    }
 
    @Override
    public List<BsLeaveInfo> NowisLeave(String userId, Date nowDate) {
        // TODO Auto-generated method stub
        return bsLeaveInfoDao.NowisLeave(userId, nowDate);
    }
 
    @Override
    public List<BsLeaveInfo> findBySendUid(String currentUserid, String auditStatus) {
        return bsLeaveInfoDao.findBySendUid(currentUserid, auditStatus);
    }
 
    @Override
    @Transactional
    public ServiceResult<Map<String, Object>> editBsLeaveInfo(BsLeaveInfo bsLeaveInfo) {
        ServiceResult<Map<String, Object>> serviceResult = new ServiceResult<Map<String, Object>>();
        if (bsLeaveInfo == null) {
            serviceResult.setParamError();
            return serviceResult;
        }
        String processId = bsLeaveInfo.getProcessId();
        WfIndex wfIndex = wfIndexDao.findByProcInstId(processId);
        String audituid = bsLeaveInfo.getAuditUid();
        if (!StringUtil.isEmpty(audituid)) {
            if (wfIndex != null) {
                String assignee = "";
                // 当前登录用户的最高机构ID
                Map<String, Object> dataResult = DepAndUserHolder
                        .getApproveUserInfo(SecurityUserHolder.getCurrentUserid(), Consts.GUID);
                if (dataResult != null && dataResult.size() > 0) {
                    Users user = (Users) dataResult.get("approveLeader");
                    if (user == null) {
                        user = (Users) dataResult.get("approveManage");
                    }
                    if (user != null) {
                        assignee = user.getUserId();
                    }
                }
                wfIndex.setAssignee(assignee);
                wfIndex.setStatus(WorkflowApplyStatusEnum.InReview.getValue());
                wfIndexDao.update(wfIndex);
            }
        }
        bsLeaveInfo.setModifyTime(DateUtil.getSystemDate());
        bsLeaveInfo.setAuditStatus(WorkflowApplyStatusEnum.Waiting.getValue());
        bsLeaveInfoDao.update(bsLeaveInfo);
        serviceResult.setMessage("提交成功！");
        return serviceResult;
    }
    /**
     * 撤销
     */
    @Override
    public ServiceResult<Map<String, Object>> revoke(String processInstanceId) {
        ServiceResult<Map<String, Object>> serviceResult = new ServiceResult<Map<String, Object>>();
        if (processInstanceId.isEmpty()) {
            serviceResult.setParamError();
            return serviceResult;
        }
        BsLeaveInfo bsLeaveInfo = findByProcessId(processInstanceId);
        if (bsLeaveInfo == null) {
            serviceResult.setParamError();
            return serviceResult;
        }
        bsLeaveInfo.setAuditStatus(WorkflowApplyStatusEnum.Revoke.getValue());
        bsLeaveInfoDao.update(bsLeaveInfo);
        return serviceResult;
    }
}
